package com.matuw.android.adapter.listview;

import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.matuw.android.adapter.ViewAdapter;
import com.matuw.android.adapter.internal.QinAdapterHelper;

import java.util.Collections;
import java.util.List;


/**
 * @author Shihwan
 * @date 2025/4/28
 */
public abstract class QinViewAdapter<VH extends QinViewHolder> extends BaseAdapter implements ViewAdapter<VH> {

    private static final int VIEW_TAG_KEY = 0x7f098000;

    protected final QinAdapterHelper helper;

    private AbsListView target;

    public QinViewAdapter() {
        this(new QinAdapterHelper());
    }

    public QinViewAdapter(QinAdapterHelper helper) {
        this.helper = helper;
    }

    @Override
    public int getCount() {
        return getItemCount();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void setTargetView(AbsListView listView) {
        this.target = listView;
    }

    @SuppressWarnings("unchecked")
    @Override
    public final View getView(int position, View convertView, ViewGroup parent) {
        Object tag;
        VH holder;
        if (convertView != null && (tag = convertView.getTag(VIEW_TAG_KEY)) != null) {
            holder = (VH) tag;
        } else {
            // 创建 convertView holder
            int viewType = getItemViewType(position);
            holder = onCreateItemHolder(parent, viewType);
            holder.get().setTag(VIEW_TAG_KEY, holder);
            helper.bindViewClickListener(this, holder, viewType);

            if (target == null && parent instanceof AbsListView) {
                target = (AbsListView) parent;
            }
        }

        holder.setAdapterPosition(position);
        render(holder, position);
        return holder.get();
    }

    @Override
    public void render(@NonNull VH holder, int position, @NonNull List<Object> payloads) {
        render(holder, position);
    }

    @Override
    public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
        helper.setOnItemViewClickedListener(listener);
    }

    @Override
    public QinViewAdapter<VH> addClickViewIds(int... ids) {
        helper.addClickViewIds(ids);
        return this;
    }

    @Override
    public QinViewAdapter<VH> setDebounceClickInterval(long interval) {
        helper.setDebounceClickInterval(interval);
        return this;
    }

    @Override
    public final int getItemViewType(int position) {
        return getItemType(position);
    }

    @Override
    public int getItemType(int position) {
        return 0;
    }

    @Override
    public void notifyItemChanged(int position) {
        AbsListView target = this.target;
        if (target == null) {
            notifyDataSetChanged();
        } else {
            int first = target.getFirstVisiblePosition();
            int last = target.getLastVisiblePosition();
            if (position >= first && position <= last) {
                View itemView = target.getChildAt(position - first);
                getView(position, itemView, target);
            }
        }
    }

    @Override
    public void notifyItemRangeChanged(int positionStart, int itemCount) {
        for (int position = positionStart; position < positionStart + itemCount; position++) {
            notifyItemChanged(position);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void notifyItemChanged(int position, @Nullable Object payload) {
        AbsListView target = this.target;
        if (target == null) {
            notifyDataSetChanged();
        } else {
            int first = target.getFirstVisiblePosition();
            int last = target.getLastVisiblePosition();
            if (position >= first && position <= last) {
                View itemView = target.getChildAt(position - first);
                Object tag = itemView == null ? null : itemView.getTag(VIEW_TAG_KEY);
                if (tag == null || payload == null) {
                    getView(position, itemView, target);
                } else {
                    VH holder = (VH) tag;
                    List<Object> list = Collections.singletonList(payload);
                    render(holder, position, list);
                }
            }
        }
    }

    @Override
    public void notifyItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
        if (this.target == null) {
            notifyDataSetChanged();
        } else {
            for (int position = positionStart; position < positionStart + itemCount; position++) {
                notifyItemChanged(position, payload);
            }
        }
    }

    @Override
    public void notifyItemInserted(int position) {
        notifyDataSetChanged();
    }

    @Override
    public void notifyItemRangeInserted(int positionStart, int itemCount) {
        notifyDataSetChanged();
    }

    @Override
    public void notifyItemRemoved(int position) {
        notifyDataSetChanged();
    }

    @Override
    public void notifyItemRangeRemoved(int positionStart, int itemCount) {
        notifyDataSetChanged();
    }
}
